/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

import Logic.AlgoritmoSingleSine3;
import Logic.SEDT2;
import Model.Temperaturas;
import Persistence.TemperaturaNBDAO;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import Logic.BemisiaTabaci;
import Model.Resultados;
import java.text.DecimalFormat;
import javax.servlet.http.HttpSession;

/**
 *
 * @author jesus
 */
@WebServlet(name = "Inferir", urlPatterns = {"/Inferir"})
public class Inferir extends HttpServlet {

    private SEDT2 sistema = new SEDT2();
    private BemisiaTabaci mosquita = new BemisiaTabaci();
    private TemperaturaNBDAO tempNBDAO = new TemperaturaNBDAO();
    private List<Temperaturas> sensorX;
    private AlgoritmoSingleSine3 aSS = null;
    private List<Resultados> resultados;
    private String modelo, autodiagnostico, basedatos;
    private List<String> fechas;
    private boolean flag = true;
    private double[] resultadoInferencia = null;
    private DecimalFormat df = new DecimalFormat("###.##");
    private String sensores[] = {"sensor_c", "sensor_n", "sensor_ne", "sensor_e", "sensor_se", "sensor_s", "sensor_so", "sensor_o", "sensor_no"};

    /** 
     * Processes requests for both HTTP <code>GET</code> and <code>POST</code> methods.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    protected void processRequest(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException, ParseException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        String fecha_inicial = null;
        String fecha_final = null;
        try {
            fecha_inicial = request.getParameter("fecha_inicial");
            fecha_final = request.getParameter("fecha_final");
            modelo = request.getParameter("modelo");
            basedatos = request.getParameter("basedatos");
            autodiagnostico = request.getParameter("autodiagnosticar");


            double por[];

            if (autodiagnostico != null) {
                HttpSession r_session = request.getSession();
                if (r_session.getAttribute("resultadosInferencia") == null) {
                    calculoUCAutodiagnostico();
                    r_session.setAttribute("resultadosInferencia", resultados);
                    r_session.setAttribute("todasFechas", fechas);
                    r_session.setAttribute("basedatos", basedatos);


                } else {

                    System.out.println("entro" + modelo);
                    List<Resultados> resultadosSesion = (List<Resultados>) r_session.getAttribute("resultadosInferencia"); //Se obtiene el usuario de la sesion
                    System.out.println(resultadosSesion);
                    List<String> fechasSesion = (List<String>) r_session.getAttribute("todasFechas");
                    String basedatosSesion = (String) r_session.getAttribute("basedatos");
                    int dias = Integer.parseInt(request.getParameter("dias"));

                    if (dias != 0) {
                        calculoAutodiagnostico(resultadosSesion, fechasSesion, dias, basedatosSesion);
                        r_session.setAttribute("resultadosInferencia", resultados);
                        r_session.setAttribute("todasFechas", fechasSesion);
                        r_session.setAttribute("basedatos", basedatosSesion);
                        System.out.println(resultados);
                    } else {
                        calculoUCAutodiagnostico();
                    }



                } } else {
                calculoUC(fecha_inicial, fecha_final, out);
            }
            if (flag) {
                String objGson = "[";
                int i = 0;
                for (Resultados r : resultados) {
                    if (i != 8) {
                        objGson = objGson + "['" + fechas.get(0) + "','" + r.getFecha() + "','" + r.getSensor() + "'," + String.valueOf(df.format(r.getPorcentaje())) + ",'" + String.valueOf(df.format(r.getUca())) + "']" + ",";
                    } else {
                        objGson = objGson + "['" + fechas.get(0) + "','" + r.getFecha() + "','" + r.getSensor() + "'," + String.valueOf(df.format(r.getPorcentaje())) + ",'" + String.valueOf(df.format(r.getUca())) + "']";
                    }
                    i++;
                }
                i = 0;
                objGson += "]";
                out.print(objGson);
            } else {
                out.print("error");
            }

        } catch (Exception e) {
//            out.print(null);
        } finally {
            out.close();
        }
    }

    // <editor-fold defaultstate="collapsed" desc="HttpServlet methods. Click on the + sign on the left to edit the code.">
    /** 
     * Handles the HTTP <code>GET</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        try {
            processRequest(request, response);
        } catch (ParseException ex) {
            Logger.getLogger(Inferir.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /** 
     * Handles the HTTP <code>POST</code> method.
     * @param request servlet request
     * @param response servlet response
     * @throws ServletException if a servlet-specific error occurs
     * @throws IOException if an I/O error occurs
     */
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        try {
            processRequest(request, response);
        } catch (ParseException ex) {
            Logger.getLogger(Inferir.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    /** 
     * Returns a short description of the servlet.
     * @return a String containing servlet description
     */
    @Override
    public String getServletInfo() {
        return "Short description";
    }// </editor-fold>

    public void calculoUC(String fechaIni, String fechaFin, PrintWriter out) throws ParseException {
        if (modelo.equals("trips")) {
            aSS = new AlgoritmoSingleSine3(9.5, 40);
        } else {//(modelo.equals("trips"))
            aSS = new AlgoritmoSingleSine3(11.5, 33);
        }
        Resultados r;
        flag = true;
        resultados = new ArrayList<Resultados>();
        fechas = tempNBDAO.getFechas(fechaIni, fechaFin, basedatos);
        if (fechas == null) {
            flag = false;
            return;
        }
        for (int i = 0; i < 9; i++) {
            sensorX = tempNBDAO.getTempS(fechas, sensores[i], basedatos);
            r = aSS.enviarUC(sensorX);
            r.setSensor(sensores[i]);
            r.setFecha(fechas.get(fechas.size() - 1));
            double ucaArray[] = {r.getUca()};
            double porcentaje[];
            if (modelo.equals("trips")) {
                porcentaje = pruebaTrips(ucaArray);
            } else//(modelo.equals("trips"))
            {
                porcentaje = pruebaMosquita(ucaArray);
            }
            r.setPorcentaje(porcentaje[0]);
            resultados.add(r);
        }
    }

    public void calculoUCAutodiagnostico() throws ParseException {


        //Aqui comienza el metodo bien!
        if (modelo.equals("trips")) {
            aSS = new AlgoritmoSingleSine3(9.5, 40);
        } else//(modelo.equals("trips"))
        {
            aSS = new AlgoritmoSingleSine3(11.5, 33);
        }

        //aSS = new AlgoritmoSingleSine3(9.5, 40); 
        resultados = new ArrayList<Resultados>();
        fechas = tempNBDAO.getTodasFechas(basedatos);
        Temperaturas t;
        //double uca = 0;
        Resultados resul;
        //List<Temperaturas> temperaturas;



        for (int i = 0; i < 9; i++) {
            double uca = 0;
            for (String fecha : fechas) {
                // temperaturas=tempNBDAO.getTempSFecha(fecha,sensores);
                // for (Temperaturas t:temperaturas) {
                t = tempNBDAO.getTempSFecha(fecha, sensores[i], basedatos);
                uca = uca + aSS.senoSimple(t.getTemperaturaMin(), t.getTemperaturaMax());
                //System.out.println(uca);
                double ucaArray[] = {uca};
                double porcentaje[] = mosquita.crispInferenceDato(ucaArray);
                if (porcentaje[0] > 50) {
                    System.out.println(uca);
                    resul = new Resultados();
                    resul.setSensor(sensores[i]);
                    resul.setFecha(fecha);
                    resul.setUca(uca);
                    resul.setPorcentaje(porcentaje[0]);
                    resultados.add(resul);
                    break;
                }
            }


        }
    }

    public void calculoAutodiagnostico(List<Resultados> resultadosSession, List<String> fechas, int dias, String basedatoss) {
        if (modelo.equals("trips")) {
            aSS = new AlgoritmoSingleSine3(9.5, 40);
        } else {
            aSS = new AlgoritmoSingleSine3(11.5, 33);
        }

        resultados = new ArrayList<Resultados>();
        Temperaturas t;
        Resultados resul;

        for (Resultados r : resultadosSession) {
            double uca = r.getUca();
            resul = new Resultados();

            String fechaResultado;
            for (int i = 1; i <= dias; i++) {
                if (fechas.get(fechas.indexOf(r.getFecha()) + i) != null) {
                    fechaResultado = fechas.get(fechas.indexOf(r.getFecha()) + i);
                    t = tempNBDAO.getTempSFecha(fechaResultado, r.getSensor(), basedatoss);
                    uca = uca + aSS.senoSimple(t.getTemperaturaMin(), t.getTemperaturaMax());
                    resul.setFecha(fechaResultado);
                } else {
                    return;
                }
            }
            System.out.println(uca);
            double ucaArray[] = {uca};
            double porcentaje[] = mosquita.crispInferenceDato(ucaArray);
            // if (porcentaje[0] > 50) {
            //resul = new Resultados();
            resul.setSensor(r.getSensor());
            //resul.setFecha(fechaResultado);
            resul.setUca(uca);
            resul.setPorcentaje(porcentaje[0]);
            resultados.add(resul);

        }

        //}
    }

    public double[] prue(double[] x) {
        return sistema.crispInference(x);
    }

    public double[] pruebaTrips(double[] x) {
        return sistema.crispInference(x);
    }

    public double[] pruebaMosquita(double[] x) {
        return mosquita.crispInferenceDato(x);
    }
}
